/**
 * 图片宫格
 * @param instance
 */
const zbImageGrid = function(instance){
    this.instance = instance;
    this.maxGrid = [1, 2, 4, 6, 9, 16, 25];
    this.content = '';

    this.tpl = '<div class="zb-grid {class_box}"> <div class="zb-grid-item {class_item}" data-params="{params}" onclick="{func}(this);"><img src="{img_url}"></div> </div>';

    this.initCss = function(){
        let flag = document.getElementsByClassName('zb-grid');
        if (!flag || flag.length === 0) {
            let style = document.createElement('style');
            style.innerText =
                '.zb-grid-item-center{display:grid;place-items: center center;}'+
                '.zb-grid-1{display:grid;grid-template-rows: 1fr; grid-gap:1px;}'+
                '.zb-grid-2{display:grid;grid-template-columns: 1fr 1fr; grid-gap:1px;}'+
                '.zb-grid-4{display:grid;grid-template-rows: 1fr 1fr; grid-template-columns: 1fr 1fr; grid-gap:1px;}'+
                '.zb-grid-6{display:grid;grid-template-rows: 1fr 1fr; grid-template-columns: 1fr 1fr 1fr; grid-gap:1px;}'+
                '.zb-grid-9{display:grid;grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr; grid-gap:1px;}'+
                '.zb-grid-16{display:grid;grid-template-rows: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr; grid-gap:1px;}'+
                '.zb-grid-25{display:grid;grid-template-rows: 1fr 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; grid-gap:1px;}'+
                '.zb-grid-item{overflow:hidden; place-self: center center;}'+
                '.zb-grid-item img {width:100%;max-width:160px;max-height:160px;}'

            let head = document.getElementsByTagName('head')[0];
            head.appendChild(style);
        }
    }

    this.init = function(arr, config){
        this.initCss();
        let maxImage = 0;
        for (let i = this.maxGrid.length - 1; i > 0; i--) {
            if (arr.length === this.maxGrid[i]) {
                maxImage = arr.length;
                break;
            }

            if (arr.length < this.maxGrid[i] && arr.length >= this.maxGrid[i-1]) {
                maxImage = this.maxGrid[i-1];
                break;
            }

        }

        arr = arr.slice(0, maxImage);

        let class_box = 'zb-grid-'+maxImage;
        let class_item = '';
        if (config && config['class_item']) {
            class_item = config['class_item'];
        }
        let tpl = this.repeatString(this.tpl, [{class_box:class_box, class_item:class_item}]);
        let dom = this.htmlToNode(tpl);
        let data = [{'zb-grid-item': arr}];
        this.content = this.repeatNode(dom, data);

    };

    //更改content
    this.updateContent = function (id) {
        document.getElementById(id).innerHTML = this.content;
    }

    //追加content
    this.appendContent = function (id) {
        document.getElementById(id).innerHTML += this.content;
    }

    this.htmlToNode = function(html) {
        let div = document.createElement('div');
        div.innerHTML = html;
        return div.firstElementChild;
    }

    this.repeatString = function (tplDom, arr, func=null) {
        if (tplDom.length === 0) {
            this.error('字符串长度为空');
            return;
        }

        if (arr.length === 0) {
            this.error('数据为空');
            return tplDom;
        }

        let tpl = tplDom;
        let out = '';
        for (let i=0; i<arr.length; i++) {
            if (typeof func === 'function') {
                arr[i] = func(arr[i]);
            }
            let map = arr[i];
            let tmp = tpl;
            for (let j in map) {
                let re = new RegExp('{' + j + '}', 'g');
                tmp = tmp.replace(re, map[j]);
            }

            let re = new RegExp('{_idx}', 'g');
            tmp = tmp.replace(re, parseInt(i)+1);

            out += tmp;
        }

        return out;
    };

    /**
     * 根据json渲染DOM节点
     * @param node HTML DOM节点, 注意不是string
     * @param arr json数组 注意是数组类型
     * @return string 返回HTML字符串, 注意不是DOM节点
     */
    this.repeatNode = function (node, arr) {
        let out = [];
        for (let i=0; i<arr.length; i++) {
            let tmp = node.outerHTML;
            tmp = tmp.replace(/\s/g, ' '); //去掉回车换行, 减少空白符

            let map = arr[i];

            //先渲染内层的数组
            for (let j in map) {
                if (map[j] instanceof Array) { //数组, 递归替换
                    let subNode = node.querySelector('.'+j);
                    if (subNode) {
                        let subHtml = this.repeatNode(subNode, map[j]); //递归
                        let subTpl = subNode.outerHTML.replace(/\s/g, ' ');
                        tmp = tmp.replace(subTpl, subHtml);
                    }
                }
            }

            //再渲染内层的对象
            for (let j in map) {
                if (map[j] instanceof Object && !(map[j] instanceof Array)) { //对象, 递归替换
                    let subNode = node.querySelector('.'+j);
                    if (subNode) {
                        let subHtml = this.repeatNode(subNode, [map[j]]); //递归
                        let subTpl = subNode.outerHTML.replace(/\s/g, ' ')
                        tmp = tmp.replace(subTpl, subHtml);
                    }
                }
            }

            //最后渲染外层的键值对/字符串
            for (let j in map) {
                if (typeof map[j] === 'string' || typeof map[j] === 'number') { //字符串, 直接替换
                    let re = new RegExp('{' + j + '}', 'g');
                    tmp = tmp.replace(re, map[j]);
                }
            }

            out.push(tmp);
        }

        return out.join('');
    }
}
/**
 * 用法举例
 * <div id="ccc" style="width: 300px"></div>
 let zbIg = new zbImageGrid('zbIg');

 let arr = [
     {img_url:'/static/img/source-code.png', params:'', func:''},
     {img_url:'/static/img/source-code.png', params:'', func:''},
     {img_url:'/static/img/source-code.png', params:'', func:''},
     {img_url:'/static/img/source-code.png', params:'', func:''},
     {img_url:'/static/img/source-code.png', params:'', func:''},
     {img_url:'/static/img/source-code.png', params:'', func:''},

     ];
 zbIg.init(arr);
 zbIg.updateContent('ccc');

 */